#include "RoomList.h"

#include <Log.h>
#include <tgmath.h>

// 获取单例对象
RoomList* RoomList::getInstance() {
    static RoomList obj;
    return &obj;
}

// 添加用户到_roomsMap中的roomName房间
void RoomList::addUser(string roomName, string userName, callback sendMessage) {
    lock_guard<mutex> locker(_mutex);
    // 在_roomsMap中搜索roomName
    if (_roomsMap.find(roomName) != _roomsMap.end()) { // 找到了roomName
        auto& value = _roomsMap[roomName];
        value.insert(make_pair(userName, sendMessage));
    }
    else { // 没找到roomName
        UserMap value = {{userName, sendMessage}};
        _roomsMap.insert(make_pair(roomName, value));
    }
}

// 通过房间名取出房间内的成员信息
UserMap RoomList::getPlayers(string roomName) {
    lock_guard<mutex> locker(_mutex);
    auto item = _roomsMap.find(roomName);
    if (item == _roomsMap.end()) {
        return UserMap();
    }
    UserMap user = item->second;
    return user;
}

// 得到当前房间中除指定玩家外的其他玩家
UserMap RoomList::getPartners(string roomName, string userName) {
    auto players = getPlayers(roomName); // 获取房间中的玩家
    if (players.size() > 1) {
        auto self = players.find(userName);
        if (self != players.end()) {
            players.erase(self); // 删除players中的指定玩家
            return players; // 返回其他玩家
        }
    }
    return UserMap();
}

// 删除指定房间中的玩家: 若房间中的玩家被全部删除完, 则删除该房间
void RoomList::removePlayer(string roomName, string userName) {
    lock_guard<mutex> locker(_mutex);
    // 找房间
    auto item = _roomsMap.find(roomName);
    if (item != _roomsMap.end()) { // 房间找到了
        // 找人
        auto players = item->second;
        auto it = players.find(userName);
        if (it != players.end() && players.size() > 1) { // 人被找到了, 并且房间中除了这个人, 还有其他人
            LogDebug("开始删除玩家, 剩余人数: %d", players.size());
            _roomsMap[roomName].erase(it); // 删除找到的人
            LogDebug("删除玩家完成, 剩余人数: %d", players.size());
        }
        else if (it != players.end() && players.size() == 1) { // 人被找到了, 并且房间中只有这一个人 -> 删除这个房间
            LogDebug("开始删除房间, 剩余人数: %d", players.size());
            _roomsMap.erase(item); // 删除这个房间
            LogDebug("删除房间完成, 剩余人数: %d", players.size());
        }
    }
}

// 清空指定房间中的所有玩家
void RoomList::removeRoom(string roomName) {
    lock_guard<mutex> locker(_mutex);
    // 找房间
    auto item = _roomsMap.find(roomName);
    if (item != _roomsMap.end()) { // 房间找到了
        _roomsMap.erase(item); // 删除这个房间
    }
}
